package com.techbh.ridecall;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.util.Log;

import com.google.android.maps.GeoPoint;

public class GeoUtil {
	private Geocoder geocoder;
	private Context context;
	private int n_results = 1;
	private int n_results_max = 5;
	private List<Address> last_search = null;
	private Location baseLocation = null;
	
	private Double lowerLeftLatitude = null;
	private Double lowerLeftLongitude = null;
	private Double upperRightLatitude = null;
	private Double upperRightLongitude = null;
	
	public GeoUtil(Context context){
		this.context = context;
		geocoder = new Geocoder(context, Locale.getDefault());
	}
	
	
	public void setBaseLocation(Location lastKnowLocation){
		baseLocation = lastKnowLocation;
		
		//Precalc borders
		if(baseLocation != null){
			
			Log.d(RideCall.APPTAG,"BaseLocation = " 
					+ baseLocation.getLatitude() + ", " 
					+ baseLocation.getLongitude() );
			
			lowerLeftLatitude = baseLocation.getLatitude() + 1;
			lowerLeftLongitude = baseLocation.getLongitude() + 1;
			upperRightLatitude = baseLocation.getLatitude() - 1;
			upperRightLongitude = baseLocation.getLongitude() - 1;

			Log.d(RideCall.APPTAG,"lowerLeftLatitude = " + lowerLeftLatitude); 
			Log.d(RideCall.APPTAG,"lowerLeftLongitude = " + lowerLeftLongitude); 
			Log.d(RideCall.APPTAG,"upperRightLatitude = " + upperRightLatitude);
			Log.d(RideCall.APPTAG,"upperRightLongitude = " + upperRightLongitude); 
		}
		
	}
	
	//Retorna candidatos de endereço a partir do "endereço" informado
	public List<Address> getLatLngsFromAddress(String endereco){
		List<Address> addresses = null;
		Log.d(RideCall.APPTAG, "Endereço a ser decodificado: " + endereco);
		try{
			if(baseLocation != null){
				//Opção para ficar mais contextualizado...
				addresses = geocoder.getFromLocationName(endereco, n_results_max, lowerLeftLatitude, lowerLeftLongitude, upperRightLatitude, upperRightLongitude);
			} else {
				addresses = geocoder.getFromLocationName(endereco, n_results_max);
			}
			
		} catch (IllegalArgumentException e){
			Log.e(RideCall.APPTAG, "Endereço vazio!" + getClass().getCanonicalName() );
		} catch (IOException e){
			Log.e(RideCall.APPTAG, "Erro na rede!" + getClass().getCanonicalName() );
		}
		
		this.last_search = addresses;
		
		return addresses;
	}
	
	//Obtem o lat e lng do 1º endereço retornado na busca pelo candidato
	public GeoPoint obterLatLngDoEndereco(String candidato){
		GeoPoint p = null;
		List<Address> a = getLatLngsFromAddress(candidato);
		if(a.size() > 0){
			Address tmpa = a.get(0);
			p = new GeoPoint(
					(int)(tmpa.getLatitude() * 1E6), 
					(int)(tmpa.getLongitude() * 1E6));
			Log.d(RideCall.APPTAG, "Endereço utilizado " + tmpa.toString());
			Log.d(RideCall.APPTAG, "Latitude e Longitude do endereço: " + p.toString());
		}
		
		return p;
	}
	
	
	public String obterEnderecoDoPonto(Double lat, Double lng){
    	String address = "";
    	GeoPoint p = new GeoPoint((int)(lat * 1E6), (int)(lng * 1E6));
		
    	Log.d(RideCall.APPTAG, "lat = " + lat);
		Log.d(RideCall.APPTAG, "lng = " + lng);
		
    	try {
    		List<Address> addresses = geocoder.getFromLocation(
    				p.getLatitudeE6()  / 1E6, 
    				p.getLongitudeE6() / 1E6, 1);

    		if (addresses.size() > 0){
    			for (int i=0; i<addresses.get(0).getMaxAddressLineIndex(); i++){
    				//Tratar somente o seguinte: rua numero, cidade, pais ?
    				address += addresses.get(0).getAddressLine(i) + "\n";
    			}
    		}

    		Log.d(RideCall.APPTAG, "Endereço : " + address);
    		//Toast.makeText(getBaseContext(), address, Toast.LENGTH_SHORT).show();
    	} catch (IllegalArgumentException e) {                
    		Log.d(RideCall.APPTAG, e.getMessage());
    	} catch (IOException e) {                
    		//e.printStackTrace();
    		Log.d(RideCall.APPTAG, e.getMessage());
    	}       	
    	return address;
	}
	
	
	public String getLastAddress(){
		String address = null;
		if (this.last_search.size() > 0){
			address = this.last_search.get(0).toString();
			Log.d(RideCall.APPTAG, "Last Address = " + address);
		}
		return address;
	}
}
